package com.xique.system.service.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xique.common.core.constant.UserConstants;
import com.xique.common.core.exception.CustomException;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.PageResult;
import com.xique.common.datascope.annotation.DataScope;
import com.xique.system.api.dto.SystemUserDTO;
import com.xique.system.bean.domain.SystemRole;
import com.xique.system.bean.domain.SystemUser;
import com.xique.system.bean.domain.SystemUserRole;
import com.xique.system.bean.search.SystemUserSearch;
import com.xique.system.mapper.SystemRoleMapper;
import com.xique.system.mapper.SystemUserMapper;
import com.xique.system.mapper.SystemUserRoleMapper;
import com.xique.system.service.service.ISystemUserService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author shd
 * @create 2021/11/3 13:39
 */
@Service
public class SystemUserServiceImpl extends ServiceImpl<SystemUserMapper, SystemUser> implements ISystemUserService {

    @Autowired
    private SystemUserMapper userMapper;

    @Autowired
    private SystemUserRoleMapper userRoleMapper;

    @Autowired
    private SystemRoleMapper roleMapper;

    @Override
    public SystemUser selectSystemUserById(Long id) {
        return userMapper.selectUserById(id);
    }

    @Override
    public SystemUser selectUserByUserName(String userName) {
        return userMapper.selectUserByUserName(userName);
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SystemUser> selectUserList(SystemUser user) {
        List<SystemUser> systemUserList = userMapper.selectUserList(user);
        if (CollectionUtil.isNotEmpty(systemUserList)) {
            systemUserList.forEach(systemUser -> {
                String roleName = systemUser.getRoleName();
                if (StrUtil.isNotBlank(roleName)) {
                    int lastIndexOf = roleName.lastIndexOf(",");
                    roleName = roleName.substring(0, lastIndexOf);
                    systemUser.setRoleName(roleName);
                }
            });
        }
        return systemUserList;
    }

    @Override
    public List<SystemUser> selectUserListByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return userMapper.selectUserListByIds(ids);
    }

    @Override
    public SystemUser selectSystemUserBySearch(SystemUserSearch search) {
        QueryWrapper<SystemUser> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(search.getUserName())) {
            wrapper.like("user_name", search.getUserName());
        }
        if (StringUtils.isNotEmpty(search.getLoginName())) {
            wrapper.like("login_name", search.getLoginName());
        }
        if (StringUtils.isNotEmpty(search.getStatus())) {
            wrapper.like("status", search.getStatus());
        }
        if (StringUtils.isNotEmpty(search.getDelFlag())) {
            wrapper.like("del_flag", search.getDelFlag());
        }
        wrapper.orderByDesc("update_time")
                .last("limit 1");
        return userMapper.selectOne(wrapper);
    }

    @Override
    public List<SystemUser> selectSystemUserListBySearch(SystemUserSearch search) {
        QueryWrapper<SystemUser> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(search.getUserName())) {
            wrapper.like("user_name", search.getUserName());
        }
        if (StringUtils.isNotEmpty(search.getLoginName())) {
            wrapper.like("login_name", search.getLoginName());
        }
        if (StringUtils.isNotEmpty(search.getStatus())) {
            wrapper.eq("status", search.getStatus());
        }
        if (StringUtils.isNotEmpty(search.getDelFlag())) {
            wrapper.eq("del_flag", search.getDelFlag());
        }
        if (CollectionUtil.isNotEmpty(search.getUserIds()) && search.getUserIds().size() >= 1) {
            wrapper.in("user_id", search.getUserIds());
        }
        if (StringUtils.isNotNull(search.getParkId())) {
            wrapper.eq("park_id", search.getParkId());
        }
        wrapper.orderByDesc("update_time");
        return userMapper.selectList(wrapper);
    }

    /**
     * 根据条件分页查询已分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SystemUser> selectAllocatedList(SystemUser user) {
        return userMapper.selectAllocatedList(user);
    }

    /**
     * 根据条件分页查询未分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SystemUser> selectUnallocatedList(SystemUser user) {
        return userMapper.selectUnallocatedList(user);
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param userName 用户名称
     * @return 结果
     */
    @Override
    public String checkUserNameUnique(String userName) {
        int count = userMapper.checkUserNameUnique(userName);
        if (count > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkLoginNameUnique(String loginName) {
        int count = userMapper.checkLoginNameUnique(loginName);
        if (count > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param user 用户信息
     */
    @Override
    public String checkPhoneUnique(SystemUser user) {
        long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        SystemUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
        if (StringUtils.isNotNull(info) && info.getUserId() != userId) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验email是否唯一
     *
     * @param user 用户信息
     */
    @Override
    public String checkEmailUnique(SystemUser user) {
        long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
        SystemUser info = userMapper.checkEmailUnique(user.getEmail());
        if (StringUtils.isNotNull(info) && info.getUserId() != userId) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验用户是否允许操作
     *
     * @param user 用户信息
     */
    @Override
    public void checkUserAllowed(SystemUser user) {
        if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) {
            throw new CustomException("不允许操作超级管理员用户");
        }
    }

    /**
     * 新增保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertUser(SystemUser user) {
        // 新增用户信息
        int rows = userMapper.insertUser(user);
        // 新增用户与角色管理
        insertUserRole(user);
        return rows;
    }

    /**
     * 新增用户角色信息
     *
     * @param user 用户对象
     */
    public void insertUserRole(SystemUser user) {
        Long[] roles = user.getRoleIds();
        if (StringUtils.isNotNull(roles)) {
            // 新增用户与角色管理
            List<SystemUserRole> list = new ArrayList<>();
            for (Long roleId : roles) {
                SystemUserRole ur = new SystemUserRole();
                ur.setUserId(user.getUserId());
                ur.setRoleId(roleId);
                list.add(ur);
            }
            if (list.size() > 0) {
                userRoleMapper.batchUserRole(list);
            }
        }
    }

    /**
     * 新增用户角色信息
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     */
    public void insertUserRole(Long userId, Long[] roleIds) {
        if (StringUtils.isNotNull(roleIds)) {
            // 新增用户与角色管理
            List<SystemUserRole> list = new ArrayList<>();
            for (Long roleId : roleIds) {
                SystemUserRole ur = new SystemUserRole();
                ur.setUserId(userId);
                ur.setRoleId(roleId);
                list.add(ur);
            }
            if (list.size() > 0) {
                userRoleMapper.batchUserRole(list);
            }
        }
    }

    /**
     * 修改保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateUser(SystemUser user) {
        Long userId = user.getUserId();
        // 删除用户与角色关联
        userRoleMapper.deleteUserRoleByUserId(userId);
        // 新增用户与角色管理
        insertUserRole(user);
        return userMapper.updateUser(user);
    }

    /**
     * 修改用户基本信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public int updateUserProfile(SystemUser user) {
        return userMapper.updateUser(user);
    }

    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteUserByIds(Long[] userIds) {
        for (Long userId : userIds) {
            checkUserAllowed(new SystemUser(userId));
        }
        // 删除用户与角色关联
        userRoleMapper.deleteUserRole(userIds);
        return userMapper.deleteUserByIds(userIds);
    }

    /**
     * 重置用户密码
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public int resetPwd(SystemUser user) {
        return userMapper.updateUser(user);
    }

    /**
     * 重置用户密码
     *
     * @param userName 用户名
     * @param password 密码
     * @return 结果
     */
    @Override
    public int resetUserPwd(String userName, String password) {
        return userMapper.resetUserPwd(userName, password);
    }

    /**
     * 修改用户状态
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public int updateUserStatus(SystemUser user) {
        return userMapper.updateUser(user);
    }

    /**
     * 用户授权角色
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     */
    @Override
    @Transactional
    public void insertUserAuth(Long userId, Long[] roleIds) {
        userRoleMapper.deleteUserRoleByUserId(userId);
        insertUserRole(userId, roleIds);
    }

    @Override
    public List<SystemUser> selectListByParkIdAndType(Long parkId, Integer type) {
        return userMapper.selectListByParkIdAndType(parkId, type);
    }

    @Override
    public PageResult selectPageList(Integer pageNum, Integer pageSize, Long userId, Long parkId, Integer type) {
        Page<SystemUser> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);

        IPage<SystemUser> pageResult = userMapper.selectPageList(page, userId, parkId, type);
        List<SystemUser> systemUserList = pageResult.getRecords();
        List<SystemUserDTO> systemUserDTOList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(systemUserList)) {
            systemUserList.forEach(systemUser -> {
                SystemUserDTO systemUserDTO = new SystemUserDTO();
                systemUserDTO.setUserId(systemUser.getUserId());
                systemUserDTO.setUserName(systemUser.getUserName());
                systemUserDTOList.add(systemUserDTO);
            });
        }
        return PageResult.builder()
                .pageNum(pageNum)
                .pageSize(pageSize)
                .totalPages(pageResult.getPages())
                .totalSize(pageResult.getTotal())
                .list(systemUserDTOList)
                .build();
    }

    /**
     * 查询用户所属角色组
     *
     * @param userName 用户名
     * @return 结果
     */
    @Override
    public String selectUserRoleGroup(String userName) {
        List<SystemRole> list = roleMapper.selectRolesByUserName(userName);
        StringBuilder idsStr = new StringBuilder();
        for (SystemRole role : list) {
            idsStr.append(role.getRoleName()).append(",");
        }
        if (StringUtils.isNotEmpty(idsStr.toString())) {
            return idsStr.substring(0, idsStr.length() - 1);
        }
        return idsStr.toString();
    }

    @Override
    public List<SystemUser> selectUserListByRoleId(Long roleId) {
        if (ObjectUtil.isEmpty(roleId)) {
            return new ArrayList<>();
        }
        return userMapper.selectUserListByRoleId(roleId);
    }
}
